package org.prail.settings;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.*;
import java.util.Properties;

import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;

import org.prail.net.Configuration;

import sun.misc.*;

public class Settings {

	private static File getDir() {
		final String home = System.getProperty("user.home");
		File dir = new File(home + "/vkmp3/");
		if (!dir.exists()) {
			dir.mkdir();
		}
		return dir;
	}

	private static File getSettingsFile() {
		return new File(getDir().getAbsolutePath() + "/settings.properties");
	}

	private static Properties get() {
		Properties prop = new Properties();
		File settings = getSettingsFile();
		if (!settings.exists()) {
			generateSettings();
		}
		try {
			prop.load(new FileInputStream(settings));
			return prop;
		} catch (IOException ex) {
			ex.printStackTrace();
		}
		return null;
	}
	
	public static boolean[] getSaveSettings() {
		boolean[] save = new boolean[2];
		Properties prop = get();
		if (prop != null) {
			String username = prop.getProperty("username");
			if (username == null || username.isEmpty()) {
				// no username set
			} else {
				save[0] = true;
			}
			String password = prop.getProperty("password");
			if (password == null || password.isEmpty()) {
				// no password set
			} else {
				save[1] = true;
			}
		}
		return save;
	}

	public static void load() {
		Properties prop = get();
		if (prop != null) {
			try {
				String username = prop.getProperty("username");
				if (username == null || username.isEmpty()) {
					System.out.println("No username set");
				} else {
					Configuration.username = AESencrp.decrypt(username);
				}
				String password = prop.getProperty("password");
				if (password == null || password.isEmpty()) {
					System.out.println("No password set");
				} else {
					Configuration.password = AESencrp.decrypt(password);
				}
				String autologin = prop.getProperty("autologin");
				if (autologin == null || autologin.isEmpty()) {
					System.out.println("Don't auto login");
				} else if (autologin.equals("true")) {
					if (Configuration.username != null
							&& Configuration.password != null) {
						Configuration.autoLogin = true;
					}
				}
				String dir = prop.getProperty("savedir");
				if (dir == null || dir.isEmpty()) {
					System.out.println("No save directory set");
				} else if (dir.equals("cur")) {
					Configuration.saveDir = new File(".");
				} else {
					Configuration.saveDir = new File(dir);
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	public static void saveSettings(final String username,
			final String password, final boolean auto, final File dir) {
		Properties prop = new Properties();
		try {
			prop.setProperty("username", AESencrp.encrypt(username));
			prop.setProperty("password", AESencrp.encrypt(password));
			prop.setProperty("autologin", auto ? "true" : "false");
			prop.setProperty("savedir", dir.getAbsolutePath());
			prop.store(new FileOutputStream(getSettingsFile()), null);
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	private static void generateSettings() {
		Properties prop = new Properties();
		try {
			prop.setProperty("username", "");
			prop.setProperty("password", "");
			prop.setProperty("autologin", "false");
			prop.setProperty("savedir", "cur");
			prop.store(new FileOutputStream(getSettingsFile()), null);
		} catch (IOException ex) {
			ex.printStackTrace();
		}
	}

	// we don't want to save username and password as plain text we'll just add
	// a simple encryption
	static class AESencrp {

		private static final String ALGO = "AES";
		private static final byte[] keyValue = new byte[] { 'T', 'h', 'e', 'B',
				'e', 's', 't', 'S', 'e', 'c', 'r', 'e', 't', 'K', 'e', 'y' };

		public static String encrypt(String Data) throws Exception {
			Key key = generateKey();
			Cipher c = Cipher.getInstance(ALGO);
			c.init(Cipher.ENCRYPT_MODE, key);
			byte[] encVal = c.doFinal(Data.getBytes());
			String encryptedValue = new BASE64Encoder().encode(encVal);
			return encryptedValue;
		}

		public static String decrypt(String encryptedData) throws Exception {
			Key key = generateKey();
			Cipher c = Cipher.getInstance(ALGO);
			c.init(Cipher.DECRYPT_MODE, key);
			byte[] decordedValue = new BASE64Decoder()
					.decodeBuffer(encryptedData);
			byte[] decValue = c.doFinal(decordedValue);
			String decryptedValue = new String(decValue);
			return decryptedValue;
		}

		private static Key generateKey() throws Exception {
			Key key = new SecretKeySpec(keyValue, ALGO);
			return key;
		}

	}

}
